(function($) {

	KOR.datepicker = function(selector, mixin) {
		return KOR.DatePicker.getInstanceOf(selector, mixin);
	};

	KOR.DatePicker = KOR.createClass(KOR.TipMenu, {

		NAME: 'datepicker',
		
		showWeek: true,
		weekStart: 0,
		calendarMonthTemplate: 'calendarMonthTemplate',
		closeOnSelect: true,
		disableDates: [],
		dateSpan: null,
		registerEvents: function(){
			var obj = this;
			this._super();
			$(document).delegate('[data-comp-id=' +this.uId+ '] .kor-prev-month', 'click', function(ev){obj.navigationHandler('setPrevMonth', ev)});
			$(document).delegate('[data-comp-id=' +this.uId+ '] .kor-next-month', 'click', function(ev){obj.navigationHandler('setNextMonth', ev)});
			$(document).delegate('[data-comp-id=' +this.uId+ '] .kor-prev-year', 'click', function(ev){obj.navigationHandler('setPrevYear', ev)});
			$(document).delegate('[data-comp-id=' +this.uId+ '] .kor-next-year', 'click', function(ev){obj.navigationHandler('setNextYear', ev)});
			$(document).delegate('[data-comp-id=' +this.uId+ '] [data-date]', 'click', $.proxy(this, 'setDateHandler'));
		},

		setDateHandler: function(ev){
			var obj = this;
			ev.preventDefault();
			
			if(!this.closeOnSelect) ev.stopPropagation();
			var target = $(ev.currentTarget);
			var trigger = $($('[data-comp-id=' +this.uId+ ']').data(this.NAME+'CurrentTrigger'));
			var cal = trigger.data('kor-calendar');						
			cal.selectDate(target.attr('data-date'), function(html){
				obj.populateOverlay(html, {target: trigger});
				trigger.val('{{}}/{{}}/{{}}'.uInject(cal.month+1, cal.date, cal.year))
			});
		},

		navigationHandler: function(calMethod, ev){
			var obj = this;
			ev.preventDefault();
			ev.stopPropagation();
			
			var trigger = $($('[data-comp-id=' +this.uId+ ']').data(this.NAME+'CurrentTrigger'));
			trigger.data('kor-calendar')[calMethod](function(html){
				obj.populateOverlay(html, {target: trigger});
			});
		},

		populate: function(ev){
		
			var obj = this;
			var target = $(ev.currentTarget);
			(target.data('kor-calendar') || target.data('kor-calendar', new KOR.Calendar({
					showWeek: this.showWeek,
					weekStart: this.weekStart,
					template: this.calendarMonthTemplate,
					disableDates: this.disableDates,
					dateSpan:this.dateSpan
					
				})).data('kor-calendar'))
				.selectFullDate(target.val(), function(html){
					
					obj.populateOverlay(html, ev);
				});
		}
		
		
		

	});

	KOR.Calendar = KOR.createClass({

		showWeek: true,
		weekStart: 0,
		template: null,
		disableDates:null,
		dateSpan: null,
		
		init: function(mixin){
			$.extend(this, mixin);
			this.disableDates = this.convertStringArrayToDate(this.disableDates);
			if(this.dateSpan != null){
				this.dateSpan.start = Date.parse(this.dateSpan.start).valueOf();
				this.dateSpan.end = Date.parse(this.dateSpan.end).valueOf();
				if(this.dateSpan.max) this.dateSpan.end = this.dateSpan.start + ( 86400000 * this.dateSpan.max)				
			}	
		},

		setPrevMonth: function(callback) {
			this.fullDate = this.fullDate || new Date();
			this.fullDate.setMonth(this.fullDate.getMonth() -1);
			this.getHTML(callback);
		},

		setNextMonth: function(callback){
			this.fullDate = this.fullDate || new Date();
			this.fullDate.setMonth(this.fullDate.getMonth() +1);
			this.getHTML(callback);
		},

		setPrevYear: function(callback) {
			this.fullDate = this.fullDate || new Date();
			this.fullDate.setFullYear(this.fullDate.getFullYear() -1);
			this.getHTML(callback);
		},

		setNextYear: function(callback){
			this.fullDate = this.fullDate || new Date();
			this.fullDate.setFullYear(this.fullDate.getFullYear() +1);
			this.getHTML(callback);
		},

		selectFullDate: function(date, callback){
			this.fullDate = new Date(date);
			if(this.fullDate.toString() == 'Invalid Date'){
				this.fullDate = new Date();
				this.selectedDate = null;
			}else{
				this.selectedDate = new Date(date)
			}
			this.getHTML(callback);
		},

		selectDate: function(date, callback){
			this.fullDate.setDate(date);
			this.selectedDate = new Date(this.fullDate);
			this.getHTML(callback);
		},

		setDate: function(date, callback){
			this.fullDate.setDate(date);
			this.getHTML(callback);
		},

		getHTML: function(callback){
			var obj = this;
			
			this.year = this.fullDate.getFullYear();
			this.month = this.fullDate.getMonth();
			this.date = this.fullDate.getDate();
			this.setDatesArray();
			KOR.ObjectFactory.getTemplate(this.template, function(html){
				KOR.ObjectFactory.getExtString('month-'+obj.month, function(str){
					obj.monthString = str;
					if(callback) callback(html.uTemplate(obj));
				});
			});
		},

		setDatesArray: function(){
			this.renderDate = new Date(this.fullDate)
			this.renderDate.setDate(1);
			this.rows = [];
			this.setInitRenderDate();
			this.processRenderDate();
		},

		setInitRenderDate: function(){
			if(!this.isRowBreakDay()){
				this.renderDate.setDate(this.renderDate.getDate() - 1);
				this.setInitRenderDate();
			}
		},

		processRenderDate: function(){
			this.setRenderRow();
			this.setRenderDay();
			this.advanceRenderer();
		},

		setRenderRow: function(){
			if(this.isRowBreakDay()){
				this.renderRow = {
					cols: []
				}
				this.rows.push(this.renderRow);
				this.renderRow.week = this.rows.length
			}
		},

		setRenderDay: function(){
			var col = {
				date: this.renderDate.getDate(),
				isInMonth: (this.renderDate.getMonth() == this.month),
				isWeekendDay: (this.renderDate.getDay() == 0 || this.renderDate.getDay() == 6),
				isCurrentDate: (this.renderDate.toString() == this.fullDate.toString()),
				isSelectedDate: (this.selectedDate && this.renderDate.toString() == this.selectedDate.toString()),
				isEnabled: this.isEnabled() 
			}
			
			this.renderRow.cols.push(col);
		},
		
		isEnabled: function(){ 
		    this.renderDate.setHours(0,0,0,0);
			if($.inArray(this.renderDate.valueOf(),this.disableDates) > -1 ) return false;
			if(this.dateSpan === null) return true; 
			if(this.renderDate.valueOf() >= this.dateSpan.start  && this.renderDate.valueOf() <= this.dateSpan.end) return true;
			return false;
		},
		
		convertStringArrayToDate: function(arr){
			$.each(arr, function(index, value){
				arr[index] = Date.parse(value);
			});
			return arr;
		},
		
		isRowBreakDay: function(){
			return this.renderDate.getDay() == this.weekStart;
		},

		advanceRenderer: function(){
			if(this.renderDate <= this.fullDate || this.renderDate.getMonth() == this.month || !this.isRowBreakDay()){
				this.renderDate.setDate(this.renderDate.getDate() +1);
				this.processRenderDate()
			} else if (this.renderRow.cols.length == 1) {
				this.rows.pop()
			}
		}
	});
	 $.extend(KOR.templates, {calendarMonthTemplate: '\
            <div class="kor-datepicker">\
                <table cellspacing="0" cellpadding="0" class="kor-datepicker-view-days">\
                    <thead>\
                        <tr>\
                            <th class="kor-prev-month-wrapper"><a class="kor-prev-month" href="#">&lt;</a></th>\
                            <th class="kor-prev-year-wrapper"><a class="kor-prev-year" href="#">&lt;&lt;</a></th>\
                            <th class="kor-month" colspan="{% if (this.showWeek) {%}4{%} else {%}3{%}%}">{{this.monthString}} {{this.year}}</th>\
                            <th class="kor-next-year-wrapper"><a class="kor-next-year" href="#">&gt;&gt;</a></th>\
                            <th class="kor-next-month-wrapper"><a class="kor-next-month" href="#">&gt;</a></th>\
                        </tr>\
                        <tr class="kor-days-of-week">\
                            {% if (this.showWeek) {%}\
                            <th><span>wk</span></th>\
                            {% } %}\
                            {% if(this.weekStart == 0) {%}\
                            <th><span>Su</span></th>\
                            {% } %}\
                            <th><span>Mo</span></th>\
                            <th><span>Tu</span></th>\
                            <th><span>We</span></th>\
                            <th><span>Th</span></th>\
                            <th><span>Fr</span></th>\
                            <th><span>Sa</span></th>\
                            {% if(this.weekStart == 1) {%}\
                            <th><span>Su</span></th>\
                            {% }%}\
                        </tr>\
                    </thead>\
                    <tbody class="kor-days">\
                            {% var obj = this; $.each(this.rows, function(i, row){ %}\
                            <tr>\
                                {% if(obj.showWeek){ %}\
                                <th class="kor-week"><a href="#"><span>{{row.week}}</span></a></th>\
                                {% } %}\
                                {% $.each(row.cols, function(i, col){ %}\
                                <td class="{% if(col.isInMonth){ %}kor-in-month {% }; if (col.isWeekendDay) { %}kor-weekend {%}; if (col.isSelectedDate) {%}kor-current-date {%}%}">\
                                    {% if(col.isInMonth && col.isEnabled){ %}<a data-date={{col.date}} href="#">{%}%}<span>{{col.date}}</span>{% if(col.isInMonth && col.isEnabled){ %}</a>{%}%}\
                                </td>\
                                {% }) %}\
                            </tr>\
                            {% }) %}\
                    </tbody>\
                </table>\
            </div>'})
})(jQuery);
